package com.itheima.security;

import com.itheima.mapper.PermissionDao;
import com.itheima.mapper.UserRoleDao;
import com.itheima.pojo.Permission;
import com.itheima.pojo.Role;
import com.itheima.pojo.User;
import com.itheima.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 基于数据库中完成认证
 */
@Service
public class SpringSecurityUserService implements UserDetailsService {

    @Autowired
    private IUserService userService;

    @Autowired
    private PermissionDao permissionDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.findByUsername(username);
        System.out.println(user);
        if (user == null) {
            throw new UsernameNotFoundException(username);// 用户名没有找到
        }
        // 先声明一个权限集合, 因为构造方法里面不能传入null
        Collection<GrantedAuthority> authorities = new ArrayList<>();

        // 查询用户对应所有权限
        List<Permission> permissions = permissionDao.findByUserId(user.getId());
        for (Permission permission : permissions) {
            // 授权
            authorities.add(new SimpleGrantedAuthority(permission.getKeyword()));
        }

        // 需要返回一个SpringSecurity的UserDetails对象
        UserDetails userDetails =
                new org.springframework.security.core.userdetails.User(user.getUsername(),
                        "{bcrypt}" + user.getPassword(),// {noop}表示不加密认证。{bcrypt} 加密认证
                        true, // 用户是否启用 true 代表启用
                        true,// 用户是否过期 true 代表未过期
                        true,// 用户凭据是否过期 true 代表未过期
                        true,// 用户是否锁定 true 代表未锁定
                        authorities);
        return userDetails;
    }
}
